package com.hulk.hyena.project.monitor.job.controller;

import com.hulk.hyena.common.constant.Constants;
import com.hulk.hyena.common.utils.poi.ExcelUtil;
import com.hulk.hyena.framework.aspectj.lang.annotation.Log;
import com.hulk.hyena.framework.aspectj.lang.enums.BusinessType;
import com.hulk.hyena.framework.web.controller.BaseController;
import com.hulk.hyena.framework.web.domain.R;
import com.hulk.hyena.framework.web.page.TableDataInfo;
import com.hulk.hyena.project.monitor.job.domain.JobLog;
import com.hulk.hyena.project.monitor.job.domain.Task;
import com.hulk.hyena.project.monitor.job.service.IJobLogService;
import com.hulk.hyena.project.monitor.job.service.IJobTaskService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;
import java.util.concurrent.Future;

/**
 * 调度任务信息操作处理
 *
 * @author hulk
 */
@Slf4j
@Controller
@RequestMapping("/monitor/job")
public class JobTaskController extends BaseController {
    private String prefix = "monitor/job" ;

    @Autowired
    private IJobTaskService jobService;
    @Autowired
    private IJobLogService jobLogService;

    @RequiresPermissions("monitor:job:view")
    @GetMapping()
    public String job() {
        return prefix + "/job" ;
    }

    @RequiresPermissions("monitor:job:list")
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(Task job) {
        startPage();
        List<Task> list = jobService.list(job);
        return getDataTable(list);
    }

    @Log(title = "定时任务", businessType = BusinessType.EXPORT)
    @RequiresPermissions("monitor:job:export")
    @PostMapping("/export")
    @ResponseBody
    public R export(Task job) {
        List<Task> list = jobService.list(job);
        ExcelUtil<Task> util = new ExcelUtil<Task>(Task.class);
        return util.exportExcel(list, "job");
    }

    @Log(title = "定时任务", businessType = BusinessType.DELETE)
    @RequiresPermissions("monitor:job:remove")
    @PostMapping("/remove")
    @ResponseBody
    public R remove(Long ids) {
        try {
            jobService.remove(ids);
            insertLog(jobService.get(ids));
            return ok();
        } catch (Exception e) {
            e.printStackTrace();
            return error(e.getMessage());
        }
    }

    /**
     * 任务调度状态修改
     */
    @Log(title = "定时任务", businessType = BusinessType.UPDATE)
    @RequiresPermissions("monitor:job:changeStatus")
    @PostMapping("/changeStatus")
    @ResponseBody
    public R changeStatus(Task job) {
        int var = jobService.changeStatus(job);
        insertLog(jobService.get(job.getId()));
        return toAjax(var);
    }

    /**
     * 任务调度立即执行一次
     */
    @Log(title = "定时任务", businessType = BusinessType.UPDATE)
    @RequiresPermissions("monitor:job:changeStatus")
    @PostMapping("/run")
    @ResponseBody
    public R run(Task job) {
        int var = jobService.runNow(job);
        insertLog(jobService.get(job.getId()));
        return toAjax(var);
    }

    /**
     * 新增调度
     */
    @GetMapping("/add")
    public String add() {
        return prefix + "/add" ;
    }

    /**
     * 新增保存调度
     */
    @Log(title = "定时任务", businessType = BusinessType.INSERT)
    @RequiresPermissions("monitor:job:add")
    @PostMapping("/add")
    @ResponseBody
    public R addSave(Task job) {
        int var = jobService.save(job);
        insertLog(jobService.get(job.getId()));
        return toAjax(var);
    }

    /**
     * 修改调度
     */
    @GetMapping("/edit/{jobId}")
    public String edit(@PathVariable("jobId") Long jobId, ModelMap mmap) {
        mmap.put("job", jobService.get(jobId));
        return prefix + "/edit" ;
    }

    /**
     * 修改保存调度
     */
    @Log(title = "定时任务", businessType = BusinessType.UPDATE)
    @RequiresPermissions("monitor:job:edit")
    @PostMapping("/edit")
    @ResponseBody
    public R editSave(Task job) {
        int var = jobService.updateCron(job);
        insertLog(jobService.get(job.getId()));
        return toAjax(var);
    }

    public void insertLog(Task job) {
        JobLog jobLog = new JobLog();
        jobLog.setJobName(job.getJobName());
        jobLog.setJobGroup(job.getJobGroup());
        jobLog.setMethodName(job.getMethodName());
        jobLog.setMethodParams(job.getMethodParams());
        jobLog.setGmtCreate(new Date());

        long startTime = System.currentTimeMillis();

        try {
            // 执行任务
            log.info("任务开始执行 - 名称：{} 方法：{}", job.getJobName(), job.getMethodName());
            long times = System.currentTimeMillis() - startTime;
            // 任务状态 0：成功 1：失败
            jobLog.setStatus(Constants.SUCCESS);
            jobLog.setJobMessage(job.getJobName() + " 总共耗时：" + times + "毫秒");

            log.info("任务执行结束 - 名称：{} 耗时：{} 毫秒", job.getJobName(), times);
        } catch (Exception e) {
            log.info("任务执行失败 - 名称：{} 方法：{}", job.getJobName(), job.getMethodName());
            log.error("任务执行异常  - ：", e);
            long times = System.currentTimeMillis() - startTime;
            jobLog.setJobMessage(job.getJobName() + " 总共耗时：" + times + "毫秒");
            // 任务状态 0：成功 1：失败
            jobLog.setStatus(Constants.FAIL);
            jobLog.setExceptionInfo(e.toString());
        } finally {
            jobLogService.addJobLog(jobLog);
        }
    }
}
